using System;
using System.Data;
using System.Data.SqlClient;
using System.Collections.Generic;
using System.Text;
using System.ComponentModel;
using Common.Utilities;

namespace Workflows.Components.Reports
{
    /// <summary></summary>
    public abstract class AggregateBase
    {
        private string _Name;
        private AggregateDataType _Type;
        private int _Count;
        private int _DistinctValueCount;
        private int _NullCount;
        private string _Mode;

        /// <summary></summary>
        public AggregateBase(string name, AggregateDataType type, int count, int distinctValCount, int nullCount)
        {
            this._Name = name;
            this._Type = type;
            this._Count = count;
            this._DistinctValueCount = distinctValCount;
            this._NullCount = nullCount;
        }

        /// <summary></summary>
        public AggregateBase(string connStr, string tblName, string columnName)
        {
            this._Name = columnName;
            this._Count = 0;
            this._DistinctValueCount = 0;
            this._NullCount = 0;

            TableColumn[] cols = DbUtil.GetTableColumns(DataProviderType.MSSQL, connStr, string.Empty, tblName);
            TableColumn col;
            if (cols != null && cols.Length > 0)
            {
                for (int i = 0; i < cols.Length; i++)
                {
                    if (cols[i].ColumnName.ToLower() == columnName.ToLower())
                    {
                        col = cols[i];
                        this._Type = Record.DistributionDataType(col.DbType);
                        break;
                    }
                }
            }
            SqlConnection conn = new SqlConnection(connStr);
            try
            {
                conn.Open();
                SqlCommand cmd = conn.CreateCommand();
                cmd.CommandText = "select count (*) from [" + tblName + "]";
                try
                {
                    this._Count = int.Parse(cmd.ExecuteScalar().ToString());
                }
                catch
                {
                    this._Count = 0;
                }
                if (this._Count > 0)
                {
                    cmd.CommandText = "select count (distinct [" + columnName + "]) from [" +
                        tblName + "]";
                    try
                    {
                        this._DistinctValueCount = int.Parse(cmd.ExecuteScalar().ToString());
                    }
                    catch
                    {
                        this._DistinctValueCount = 0;
                    }

                    cmd.CommandText = "select count (*) from [" + tblName + "] where [" +
                        columnName + "] is null";
                    try
                    {
                        this._NullCount = int.Parse(cmd.ExecuteScalar().ToString());
                    }
                    catch
                    {
                        this._NullCount = 0;
                    }

                    cmd.CommandText = "select top 1 [" + columnName + "] from [" +
                        tblName + "] where [" + columnName + "] is not null " +
                        "order by [" + columnName + "] desc";
                    try
                    {
                        this._Mode = cmd.ExecuteScalar().ToString();
                    }
                    catch
                    {
                        this._Mode = string.Empty;
                    }
                }
                else
                {
                    throw new Exception("The table is empty");
                }
            }
            catch (Exception ex)
            {
                ExceptionHandler.HandlesException(ex);
            }
            finally
            {
                conn.Close();
            }
        }

        #region properties
        /// <summary></summary>
        [Browsable(true)]
        public string Name
        {
            get
            {
                return this._Name;
            }
            set
            {
                this._Name = value;
            }
        }

        /// <summary></summary>
        [Browsable(true)]
        public AggregateDataType Type
        {
            get
            {
                return this._Type;
            }
            set
            {
                this._Type = value;
            }
        }

        /// <summary></summary>
        [Browsable(true), Category("Stats")]
        public int Count
        {
            get
            {
                return this._Count;
            }
            set
            {
                this._Count = value;
            }
        }

        /// <summary></summary>
        [Browsable(true), Category("Stats")]
        public int DistinctValueCount
        {
            get
            {
                return this._DistinctValueCount;
            }
            set
            {
                this._DistinctValueCount = value;
            }
        }

        /// <summary></summary>
        [Browsable(true), Category("Stats")]
        public int NullValueCount
        {
            get
            {
                return this._NullCount;
            }
            set
            {
                this._NullCount = value;
            }
        }

        /// <summary></summary>
        [Browsable(true), Category("Stats")]
        public virtual string Mode
        {
            get { return _Mode; }
        }

        #endregion
    }
}
